package com.evolved.automata.examples.sudoku;
import java.util.*;
import com.evolved.automata.*;
import com.evolved.automata.filetools.*;

public class SudokuBoard implements CSVRowImporter {
	// This actually stored LinkedList<Integer>
	private LinkedList[][] j_BoardDefinition;
	BoardUtilities j_BoardConstraintUtility;


	
	/**
	 * Returns false if board definition is inconsistent
	 * @param boardDefFileFullName
	 */
	public boolean Initialize(String boardDefFileFullName){
		j_BoardDefinition = new LinkedList[9][9];
		StandardTools.ImportCSVFile(boardDefFileFullName, this, true);
		j_BoardConstraintUtility= new BoardUtilities(j_BoardDefinition);
		
		LinkedList[][] tempBoardDefinition =new LinkedList[9][9];
		for (int i=0;i<9;i++)
		{
			for (int j=0;j<9;j++)
			{
				if (j_BoardDefinition[i][j]==null)
				{
					tempBoardDefinition[i][j]=j_BoardConstraintUtility.GetChoices(i, j);
					if (tempBoardDefinition[i][j].size()==0)
						return false;
					
				}
			}
		}
		// Merge temp board into original board
		for (int i=0;i<9;i++)
		{
			for (int j=0;j<9;j++)
			{
				if (j_BoardDefinition[i][j]==null)
				{
					j_BoardDefinition[i][j]=tempBoardDefinition[i][j];
					
				}
			}
		}
		
		
		return true;
	}
	
	public boolean FinishedP()
	{
		Integer value;
		for (int i=0;i<9;i++)
		{
			for (int j=0;j<9;j++)
			{
				value=j_BoardConstraintUtility.GetDefiniteValue(i,j);
				if (value == null)
					return false;
			}
		}
		return true;
	}


	
	
	// This version is not used
	public void ImportCellData(String cell)
	{
		
	}
	public void ImportCellData(String cell, int row, int column)
	{
		LinkedList<Integer> cellValue = new LinkedList<Integer>();
		if (cell.length()>0)
		{	
			cellValue.add(new Integer(Integer.parseInt(cell)-1));
			j_BoardDefinition[row][column]=cellValue;
		}
	}
	
	public SudokuChoiceNode GetChoiceNode()
	{
		SudokuAction sudoAction;

		IntPair leasttOptionCell=null;
		int leastNumberOfOptions=0, tempSize;
		boolean first=true;
		LinkedList<Integer> possibleValues;
		for (int i=0;i<9;i++)
		{
			for (int j=0;j<9;j++)
			{
				possibleValues=j_BoardDefinition[i][j];
				tempSize=possibleValues.size();
				if ((first||tempSize<=leastNumberOfOptions)&&(tempSize>1))
				{
					leastNumberOfOptions=tempSize;
					first=false;
					leasttOptionCell=new IntPair(i,j);
				}
				
			}
		}
		SudokuChoiceNode choiceNode = new SudokuChoiceNode(this);
		possibleValues=j_BoardDefinition[leasttOptionCell.GetFirst()][leasttOptionCell.GetSecond()];
		for (Integer value:possibleValues)
		{
			sudoAction = new SudokuAction(this,leasttOptionCell.GetFirst(),leasttOptionCell.GetSecond(),value);
			choiceNode.AddActionPossibility(sudoAction);
		}
		return choiceNode;
		
	}
	
	
	public LinkedList[][] GetDefinition()
	{
		return j_BoardDefinition;
	}
	
	public BoardUtilities GetUtilities()
	{
		return j_BoardConstraintUtility;
	}
}
